.PAGE:0
PST R0, 68  // clear screen
LIM R1, 27  // draw bottom of column bars
PST R1, 65
PST R1, 67
LIM R0, 1
PST R0, 64
PST R1, 86

LIM R1, 4  // reset counter
LOOPSRC .gaploop  // add gaps between bars
LOOPCNT 5
PST R1, 90  // load x1 and erase
.gaploop
ADI R1, R1, 4  // move to next bar

LIM R6, 1  // load first turn
LIM R7, 4  // load initial arrow position

CAL .setupsprites  // load sprite data

.mainloop  // let the game begin!
LIM R0, 28  // erase bottom rectangle
PST R0, 65
LIM R1, 31
PST R1, 66
PST R1, 67
PST R0, 92
BSLI R4, R7, 2  // draw arrow
ADI R4, R4, -4
PST R4, 64
PLD R0, 112

CAL .outputturn  // output turn
PLD R0, 69  // buffer screen

PLD R1, 0  // get controller inputs
CMA R1, 1  // check if moving right
BRT ZERO, .skipright
ADI R7, R7, 1  // move arrow and continue loop
JMP .mainloop

.skipright
CMA R1, 8  // check if moving left
BRT ZERO, .skipleft
ADI R7, R7, -1  // move arrow and continue loop
JMP .mainloop

.skipleft
CMA R1, 16  // check if any buttons pressed at all
BRN ZERO, .mainloop  // if not, continue loop

POI R7  // get number of pieces in column so far
MLD R1, 0
ADI R1, R1, 1  // add another piece
POI R7  // store again
MST R1, 0

BSLI R2, R7, 3  // store in memory board
ADD R2, R2, R1
ADI R3, R6, 1
POI R2
MST R3, 0

BSLI R1, R1, 2  // draw sprite to screen
LIM R0, 26
SUB R1, R0, R1
PST R1, 65
POI R6
PLD R0, 113

ADI R6, R6, 1  // flip turn
AIM R6, 1

JMP .windetect  // check if won



.PAGE:1
.setupsprites
LIM R0, 0b00001010  // load up arrow sprite (0)
PST R0, 96
LIM R0, 0b01000000
PST R0, 104

LIM R0, 0b11101010  // load O sprite (1)
PST R0, 97
LIM R0, 0b11100000
PST R0, 105

LIM R0, 0b10100100  // load X sprite (2)
PST R0, 98
LIM R0, 0b10100000
PST R0, 106

RET  // return


.outputturn
PST R0, 70  // clear char display
LIM R0, "P"  // write PLAYER
PST R0, 72
LIM R0, "L"
PST R0, 72
LIM R0, "A"
PST R0, 72
LIM R0, "Y"
PST R0, 72
LIM R0, "E"
PST R0, 72
LIM R0, "R"
PST R0, 72
PST R0, 72

BSLI R5, R6, 3  // output X or O
ADD R5, R5, R6
LIM R0, "O"
ADD R5, R5, R0
PST R5, 72
PST R0, 72  // blank out rest of row
PST R0, 72
PST R0, 72
PLD R0, 72  // make sure screen is not getting overloaded

LIM R0, "T"  // output TURN
PST R0, 73
LIM R0, "U"
PST R0, 73
LIM R0, "R"
PST R0, 73
LIM R0, "N"
PST R0, 73
PST R0, 73  // blank out rest of row
PST R0, 73
PST R0, 73
PST R0, 73
PST R0, 73
PST R0, 73
PST R0, 73
PST R0, 73

RET  // return



.PAGE:2
.checkwinline
LIM R3, 3  // cumulative AND
LOOPSRC .checkwinloop  // setup loop
LOOPCNT 3

POP R1  // get piece
POI R1
MLD R2, 0
.checkwinloop
AND R3, R2, R3  // add to cumulative AND

BRN NZERO, .won  // return if not won
RET

.won
PST R0, 70  // clear char display
LIM R0, "P"  // write PLAYER
PST R0, 72
LIM R0, "L"
PST R0, 72
LIM R0, "A"
PST R0, 72
LIM R0, "Y"
PST R0, 72
LIM R0, "E"
PST R0, 72
LIM R0, "R"
PST R0, 72
PST R0, 72

ADI R3, R3, -1  // adjust turn
BSLI R5, R3, 3  // output X or O
ADD R5, R5, R3
LIM R0, "O"
ADD R5, R5, R0
PST R5, 72
PST R0, 72  // blank out rest of row
PST R0, 72
PST R0, 72
PLD R0, 72  // make sure screen is not getting overloaded

LIM R0, "W"  // output WINS
PST R0, 73
LIM R0, "I"
PST R0, 73
LIM R0, "N"
PST R0, 73
LIM R0, "S"
PST R0, 73
PST R0, 73  // blank out rest of row
PST R0, 73
PST R0, 73
PST R0, 73
PST R0, 73
PST R0, 73
PST R0, 73
PST R0, 73

PST R0, 69  // buffer screen
HLT  // game over!


.PAGE:3
.windetect
// this bit was all generated by a python program
LIM R0, 9  // AUTOGENERATED horizontal_0
PSH R0
LIM R0, 17
PSH R0
LIM R0, 25
PSH R0
LIM R0, 33
PSH R0
CAL .checkwinline
LIM R0, 10  // AUTOGENERATED horizontal_1
PSH R0
LIM R0, 18
PSH R0
LIM R0, 26
PSH R0
LIM R0, 34
PSH R0
CAL .checkwinline
LIM R0, 11  // AUTOGENERATED horizontal_2
PSH R0
LIM R0, 19
PSH R0
LIM R0, 27
PSH R0
LIM R0, 35
PSH R0
CAL .checkwinline
LIM R0, 12  // AUTOGENERATED horizontal_3
PSH R0
LIM R0, 20
PSH R0
LIM R0, 28
PSH R0
LIM R0, 36
PSH R0
CAL .checkwinline
LIM R0, 13  // AUTOGENERATED horizontal_4
PSH R0
LIM R0, 21
PSH R0
LIM R0, 29
PSH R0
LIM R0, 37
PSH R0
CAL .checkwinline
LIM R0, 14  // AUTOGENERATED horizontal_5
PSH R0
LIM R0, 22
PSH R0
LIM R0, 30
PSH R0
LIM R0, 38
PSH R0
CAL .checkwinline
LIM R0, 17  // AUTOGENERATED horizontal_6
PSH R0
LIM R0, 25
PSH R0
LIM R0, 33
PSH R0
LIM R0, 41
PSH R0
CAL .checkwinline
JMP .windetect2


.PAGE:4
.windetect2
LIM R0, 18  // AUTOGENERATED horizontal_7
PSH R0
LIM R0, 26
PSH R0
LIM R0, 34
PSH R0
LIM R0, 42
PSH R0
CAL .checkwinline
LIM R0, 19  // AUTOGENERATED horizontal_8
PSH R0
LIM R0, 27
PSH R0
LIM R0, 35
PSH R0
LIM R0, 43
PSH R0
CAL .checkwinline
LIM R0, 20  // AUTOGENERATED horizontal_9
PSH R0
LIM R0, 28
PSH R0
LIM R0, 36
PSH R0
LIM R0, 44
PSH R0
CAL .checkwinline
LIM R0, 21  // AUTOGENERATED horizontal_10
PSH R0
LIM R0, 29
PSH R0
LIM R0, 37
PSH R0
LIM R0, 45
PSH R0
CAL .checkwinline
LIM R0, 22  // AUTOGENERATED horizontal_11
PSH R0
LIM R0, 30
PSH R0
LIM R0, 38
PSH R0
LIM R0, 46
PSH R0
CAL .checkwinline
LIM R0, 25  // AUTOGENERATED horizontal_12
PSH R0
LIM R0, 33
PSH R0
LIM R0, 41
PSH R0
LIM R0, 49
PSH R0
CAL .checkwinline
LIM R0, 26  // AUTOGENERATED horizontal_13
PSH R0
LIM R0, 34
PSH R0
LIM R0, 42
PSH R0
LIM R0, 50
PSH R0
CAL .checkwinline
JMP .windetect3


.PAGE:5
.windetect3
LIM R0, 27  // AUTOGENERATED horizontal_14
PSH R0
LIM R0, 35
PSH R0
LIM R0, 43
PSH R0
LIM R0, 51
PSH R0
CAL .checkwinline
LIM R0, 28  // AUTOGENERATED horizontal_15
PSH R0
LIM R0, 36
PSH R0
LIM R0, 44
PSH R0
LIM R0, 52
PSH R0
CAL .checkwinline
LIM R0, 29  // AUTOGENERATED horizontal_16
PSH R0
LIM R0, 37
PSH R0
LIM R0, 45
PSH R0
LIM R0, 53
PSH R0
CAL .checkwinline
LIM R0, 30  // AUTOGENERATED horizontal_17
PSH R0
LIM R0, 38
PSH R0
LIM R0, 46
PSH R0
LIM R0, 54
PSH R0
CAL .checkwinline
LIM R0, 33  // AUTOGENERATED horizontal_18
PSH R0
LIM R0, 41
PSH R0
LIM R0, 49
PSH R0
LIM R0, 57
PSH R0
CAL .checkwinline
LIM R0, 34  // AUTOGENERATED horizontal_19
PSH R0
LIM R0, 42
PSH R0
LIM R0, 50
PSH R0
LIM R0, 58
PSH R0
CAL .checkwinline
LIM R0, 35  // AUTOGENERATED horizontal_20
PSH R0
LIM R0, 43
PSH R0
LIM R0, 51
PSH R0
LIM R0, 59
PSH R0
CAL .checkwinline
JMP .windetect4


.PAGE:6
.windetect4
LIM R0, 36  // AUTOGENERATED horizontal_21
PSH R0
LIM R0, 44
PSH R0
LIM R0, 52
PSH R0
LIM R0, 60
PSH R0
CAL .checkwinline
LIM R0, 37  // AUTOGENERATED horizontal_22
PSH R0
LIM R0, 45
PSH R0
LIM R0, 53
PSH R0
LIM R0, 61
PSH R0
CAL .checkwinline
LIM R0, 38  // AUTOGENERATED horizontal_23
PSH R0
LIM R0, 46
PSH R0
LIM R0, 54
PSH R0
LIM R0, 62
PSH R0
CAL .checkwinline
LIM R0, 9  // AUTOGENERATED vertical_0
PSH R0
LIM R0, 10
PSH R0
LIM R0, 11
PSH R0
LIM R0, 12
PSH R0
CAL .checkwinline
LIM R0, 10  // AUTOGENERATED vertical_1
PSH R0
LIM R0, 11
PSH R0
LIM R0, 12
PSH R0
LIM R0, 13
PSH R0
CAL .checkwinline
LIM R0, 11  // AUTOGENERATED vertical_2
PSH R0
LIM R0, 12
PSH R0
LIM R0, 13
PSH R0
LIM R0, 14
PSH R0
CAL .checkwinline
LIM R0, 17  // AUTOGENERATED vertical_3
PSH R0
LIM R0, 18
PSH R0
LIM R0, 19
PSH R0
LIM R0, 20
PSH R0
CAL .checkwinline
JMP .windetect5


.PAGE:7
.windetect5
LIM R0, 18  // AUTOGENERATED vertical_4
PSH R0
LIM R0, 19
PSH R0
LIM R0, 20
PSH R0
LIM R0, 21
PSH R0
CAL .checkwinline
LIM R0, 19  // AUTOGENERATED vertical_5
PSH R0
LIM R0, 20
PSH R0
LIM R0, 21
PSH R0
LIM R0, 22
PSH R0
CAL .checkwinline
LIM R0, 25  // AUTOGENERATED vertical_6
PSH R0
LIM R0, 26
PSH R0
LIM R0, 27
PSH R0
LIM R0, 28
PSH R0
CAL .checkwinline
LIM R0, 26  // AUTOGENERATED vertical_7
PSH R0
LIM R0, 27
PSH R0
LIM R0, 28
PSH R0
LIM R0, 29
PSH R0
CAL .checkwinline
LIM R0, 27  // AUTOGENERATED vertical_8
PSH R0
LIM R0, 28
PSH R0
LIM R0, 29
PSH R0
LIM R0, 30
PSH R0
CAL .checkwinline
LIM R0, 33  // AUTOGENERATED vertical_9
PSH R0
LIM R0, 34
PSH R0
LIM R0, 35
PSH R0
LIM R0, 36
PSH R0
CAL .checkwinline
LIM R0, 34  // AUTOGENERATED vertical_10
PSH R0
LIM R0, 35
PSH R0
LIM R0, 36
PSH R0
LIM R0, 37
PSH R0
CAL .checkwinline
JMP .windetect6


.PAGE:8
.windetect6
LIM R0, 35  // AUTOGENERATED vertical_11
PSH R0
LIM R0, 36
PSH R0
LIM R0, 37
PSH R0
LIM R0, 38
PSH R0
CAL .checkwinline
LIM R0, 41  // AUTOGENERATED vertical_12
PSH R0
LIM R0, 42
PSH R0
LIM R0, 43
PSH R0
LIM R0, 44
PSH R0
CAL .checkwinline
LIM R0, 42  // AUTOGENERATED vertical_13
PSH R0
LIM R0, 43
PSH R0
LIM R0, 44
PSH R0
LIM R0, 45
PSH R0
CAL .checkwinline
LIM R0, 43  // AUTOGENERATED vertical_14
PSH R0
LIM R0, 44
PSH R0
LIM R0, 45
PSH R0
LIM R0, 46
PSH R0
CAL .checkwinline
LIM R0, 49  // AUTOGENERATED vertical_15
PSH R0
LIM R0, 50
PSH R0
LIM R0, 51
PSH R0
LIM R0, 52
PSH R0
CAL .checkwinline
LIM R0, 50  // AUTOGENERATED vertical_16
PSH R0
LIM R0, 51
PSH R0
LIM R0, 52
PSH R0
LIM R0, 53
PSH R0
CAL .checkwinline
LIM R0, 51  // AUTOGENERATED vertical_17
PSH R0
LIM R0, 52
PSH R0
LIM R0, 53
PSH R0
LIM R0, 54
PSH R0
CAL .checkwinline
JMP .windetect7


.PAGE:9
.windetect7
LIM R0, 57  // AUTOGENERATED vertical_18
PSH R0
LIM R0, 58
PSH R0
LIM R0, 59
PSH R0
LIM R0, 60
PSH R0
CAL .checkwinline
LIM R0, 58  // AUTOGENERATED vertical_19
PSH R0
LIM R0, 59
PSH R0
LIM R0, 60
PSH R0
LIM R0, 61
PSH R0
CAL .checkwinline
LIM R0, 59  // AUTOGENERATED vertical_20
PSH R0
LIM R0, 60
PSH R0
LIM R0, 61
PSH R0
LIM R0, 62
PSH R0
CAL .checkwinline
LIM R0, 9  // AUTOGENERATED diagonal_right_0
PSH R0
LIM R0, 18
PSH R0
LIM R0, 27
PSH R0
LIM R0, 36
PSH R0
CAL .checkwinline
LIM R0, 10  // AUTOGENERATED diagonal_right_1
PSH R0
LIM R0, 19
PSH R0
LIM R0, 28
PSH R0
LIM R0, 37
PSH R0
CAL .checkwinline
LIM R0, 11  // AUTOGENERATED diagonal_right_2
PSH R0
LIM R0, 20
PSH R0
LIM R0, 29
PSH R0
LIM R0, 38
PSH R0
CAL .checkwinline
LIM R0, 17  // AUTOGENERATED diagonal_right_3
PSH R0
LIM R0, 26
PSH R0
LIM R0, 35
PSH R0
LIM R0, 44
PSH R0
CAL .checkwinline
JMP .windetect8


.PAGE:10
.windetect8
LIM R0, 18  // AUTOGENERATED diagonal_right_4
PSH R0
LIM R0, 27
PSH R0
LIM R0, 36
PSH R0
LIM R0, 45
PSH R0
CAL .checkwinline
LIM R0, 19  // AUTOGENERATED diagonal_right_5
PSH R0
LIM R0, 28
PSH R0
LIM R0, 37
PSH R0
LIM R0, 46
PSH R0
CAL .checkwinline
LIM R0, 25  // AUTOGENERATED diagonal_right_6
PSH R0
LIM R0, 34
PSH R0
LIM R0, 43
PSH R0
LIM R0, 52
PSH R0
CAL .checkwinline
LIM R0, 26  // AUTOGENERATED diagonal_right_7
PSH R0
LIM R0, 35
PSH R0
LIM R0, 44
PSH R0
LIM R0, 53
PSH R0
CAL .checkwinline
LIM R0, 27  // AUTOGENERATED diagonal_right_8
PSH R0
LIM R0, 36
PSH R0
LIM R0, 45
PSH R0
LIM R0, 54
PSH R0
CAL .checkwinline
LIM R0, 33  // AUTOGENERATED diagonal_right_9
PSH R0
LIM R0, 42
PSH R0
LIM R0, 51
PSH R0
LIM R0, 60
PSH R0
CAL .checkwinline
LIM R0, 34  // AUTOGENERATED diagonal_right_10
PSH R0
LIM R0, 43
PSH R0
LIM R0, 52
PSH R0
LIM R0, 61
PSH R0
CAL .checkwinline
JMP .windetect9


.PAGE:11
.windetect9
LIM R0, 35  // AUTOGENERATED diagonal_right_11
PSH R0
LIM R0, 44
PSH R0
LIM R0, 53
PSH R0
LIM R0, 62
PSH R0
CAL .checkwinline
LIM R0, 12  // AUTOGENERATED diagonal_left_0
PSH R0
LIM R0, 19
PSH R0
LIM R0, 26
PSH R0
LIM R0, 33
PSH R0
CAL .checkwinline
LIM R0, 13  // AUTOGENERATED diagonal_left_1
PSH R0
LIM R0, 20
PSH R0
LIM R0, 27
PSH R0
LIM R0, 34
PSH R0
CAL .checkwinline
LIM R0, 14  // AUTOGENERATED diagonal_left_2
PSH R0
LIM R0, 21
PSH R0
LIM R0, 28
PSH R0
LIM R0, 35
PSH R0
CAL .checkwinline
LIM R0, 20  // AUTOGENERATED diagonal_left_3
PSH R0
LIM R0, 27
PSH R0
LIM R0, 34
PSH R0
LIM R0, 41
PSH R0
CAL .checkwinline
LIM R0, 21  // AUTOGENERATED diagonal_left_4
PSH R0
LIM R0, 28
PSH R0
LIM R0, 35
PSH R0
LIM R0, 42
PSH R0
CAL .checkwinline
LIM R0, 22  // AUTOGENERATED diagonal_left_5
PSH R0
LIM R0, 29
PSH R0
LIM R0, 36
PSH R0
LIM R0, 43
PSH R0
CAL .checkwinline
JMP .windetect10


.PAGE:12
.windetect10
LIM R0, 28  // AUTOGENERATED diagonal_left_6
PSH R0
LIM R0, 35
PSH R0
LIM R0, 42
PSH R0
LIM R0, 49
PSH R0
CAL .checkwinline
LIM R0, 29  // AUTOGENERATED diagonal_left_7
PSH R0
LIM R0, 36
PSH R0
LIM R0, 43
PSH R0
LIM R0, 50
PSH R0
CAL .checkwinline
LIM R0, 30  // AUTOGENERATED diagonal_left_8
PSH R0
LIM R0, 37
PSH R0
LIM R0, 44
PSH R0
LIM R0, 51
PSH R0
CAL .checkwinline
LIM R0, 36  // AUTOGENERATED diagonal_left_9
PSH R0
LIM R0, 43
PSH R0
LIM R0, 50
PSH R0
LIM R0, 57
PSH R0
CAL .checkwinline
LIM R0, 37  // AUTOGENERATED diagonal_left_10
PSH R0
LIM R0, 44
PSH R0
LIM R0, 51
PSH R0
LIM R0, 58
PSH R0
CAL .checkwinline
LIM R0, 38  // AUTOGENERATED diagonal_left_11
PSH R0
LIM R0, 45
PSH R0
LIM R0, 52
PSH R0
LIM R0, 59
PSH R0
CAL .checkwinline
JMP .mainloop
